package widget.common.tools
{
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	
	import widget.common.event.LoadDataEvent;
	
	[Event(name="completeLoader" , type="widget.common.event.LoadDataEvent")]
	[Event(name="timeOutLoader" , type="widget.common.event.LoadDataEvent")]
	public class XMLFileLoader extends EventDispatcher
	{
		private var url : String = null;
		private var loader : URLLoader = null;
		private var loadInfo : String = null;
		private var format : String = URLLoaderDataFormat.TEXT;

		/**
		 * 连接次数
		 */
		private var connectNum : int = 0;
		/**
		 * 加载进度时间监听
		 */
		private var progressTimer : Timer = null;
		/**
		 * 时间计数器
		 */
		private var timerCounter : int = 0;
		/**
		 * 连接失败次数计数器
		 */
		private var failedCounter : int = 0;
		/**
		 * 重新次数连接计数器
		 */
		private var reconnectNum : int = 0;

		public function XMLFileLoader()
		{
			super();
			//this.url = url;
			//this.loadInfo = tag;
			XML.ignoreComments = true;
			XML.ignoreWhitespace = true;
			XML.ignoreProcessingInstructions = true;
			if (url)
				load();
		}

		private function load() : void
		{
			var request : URLRequest = new URLRequest(url);
			loader = new URLLoader();
			loader.dataFormat = format;
			configureListeners(loader);

			try
			{
				loader.load(request);
			}
			catch (error : Error)
			{
				throw new Error("Unable to load requested file!!!");
			}

			progressTimer = new Timer(1000);
			progressTimer.start();
			progressTimer.addEventListener(TimerEvent.TIMER , timerHandler);
		}

		private function reload() : void
		{
			var request : URLRequest = new URLRequest(url);
			try
			{
				loader.close();
			}
			catch (e : IOError)
			{
				throw new Error("can not close this connection!!!");
			}
			try
			{
				loader.load(request);
			}
			catch (error : Error)
			{
				throw new Error("Unable to load requested file!!!");
			}

		}

		private function configureListeners(dispatcher : IEventDispatcher) : void
		{
			dispatcher.addEventListener(Event.COMPLETE , loadCompleteHandler);
			dispatcher.addEventListener(Event.OPEN , openHandler);
			dispatcher.addEventListener(ProgressEvent.PROGRESS , progressHandler);
			dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR , securityErrorHandler);
			dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS , httpStatusHandler);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR , ioErrorHandler);
		}

		private function removeListeners() : void
		{
			loader.removeEventListener(Event.COMPLETE , loadCompleteHandler);
			loader.removeEventListener(Event.OPEN , openHandler);
			loader.removeEventListener(ProgressEvent.PROGRESS , progressHandler);
			loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR , securityErrorHandler);
			loader.removeEventListener(HTTPStatusEvent.HTTP_STATUS , httpStatusHandler);
			loader.removeEventListener(IOErrorEvent.IO_ERROR , ioErrorHandler);
		}

		/**
		 * 控制重新连接服务器
		 * @param event
		 *
		 */
		private function timerHandler(event : TimerEvent) : void
		{

			if (timerCounter == connectNum)
			{
				//掉线需要重新连接
				failedCounter++;

				if (failedCounter == 3)
				{
					failedCounter = 0;
					reconnectNum++;
					reload();
				}

				if (reconnectNum == 5)
				{
					//网络断掉
					clearTimer();
				}
			}
			else
			{
				timerCounter = connectNum;
			}
		}

		private function openHandler(e : Event) : void
		{
			//trace ("opened")

			this.dispatchEvent(e);
		}

		private function ioErrorHandler(e : IOErrorEvent) : void
		{
		}

		private function securityErrorHandler(e : SecurityErrorEvent) : void
		{

		}

		private function httpStatusHandler(e : HTTPStatusEvent) : void
		{
			this.dispatchEvent(e);
		}


		private function loadCompleteHandler(event : Event) : void
		{
			var loader : URLLoader = URLLoader(event.target);
			clearTimer();
			this.dispatchEvent(new LoadDataEvent(LoadDataEvent.COMPLETE_LOADER , loader.data));
		}

		private function progressHandler(event : ProgressEvent) : void
		{
			connectNum++;
			// trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
		}

		private function clearTimer() : void
		{
			reconnectNum = 0;
			if (progressTimer != null)
			{
				progressTimer.stop();
				progressTimer.removeEventListener(TimerEvent.TIMER , this.timerHandler);
			}
			progressTimer = null;
		}

		public function loadData(uri : String , type : String = URLLoaderDataFormat.TEXT) : void
		{
			this.url = uri;
			this.format = type;
			load();
		}

		public function clear() : void
		{
			removeListeners();
			loader.close();
			progressTimer = null;
			loader = null;
		}
	}
}



